import * as math from 'mathjs';
import {exp} from "mathjs";

// 匹配views里面所有的.vue文件
const modules = import.meta.glob('./../views/**/*.vue')

/*
* token的key值为userToken
* 目前token存储在sessionStorage里面
*/

// 获取cookie里面的token
export const getCookie = () => {
    const cookie = document.cookie.replace(/(?:(?:^|.*;\s*)Authorization\s*\=\s*([^;]*).*$)|^.*$/, "$1");
    return cookie
}

// 从地址获取token
export const hrefGetToken = () => {
    const paramsJSON = defaultTo(window.location.search.split('?')[1], '')
    const paramsList = defaultTo(paramsJSON.split('&'), [])

    const key = paramsList.findIndex(item => {
        return item.indexOf('id=') > -1
    })
    return key > -1 ? paramsList[key].split('id=')[1] : ''
}

// 编辑地址token
export const hrefSetToken = (token) => {
    window.location.search = `id=${token}`
}

// 删除地址token
export const hrefRemoveToken = () => {
    window.location.search = ''
}

// 查询token
export const getToken = () => {
    return sessionStorage.getItem('userToken')
}

// 编辑token
export const setToken = () => {
    const token = hrefGetToken()
    sessionStorage.setItem('userToken', token)
    return token
}

// 删除token
export const removeToken = () => {
    sessionStorage.removeItem('userToken')
}

// 请求异常处理
export const errorRequest = (res) => {
    const code = res.data?.code || res.code || 200
    const showMessage = res?.config?.showMessage || true
    const message = res?.data?.msg || res.msg || ''
    const isLoginCode = [40101, 40107] // 登录页状态码
    const is401Code = [40100, 40102, 40103, 40104, 40105, 40106] // 401页状态码

    // token过期/套餐过期后后清除路由上的token
    if (isLoginCode.includes(code)) {
        sessionStorage.setItem('is404', 'false')
        hrefRemoveToken()
        return 'error'
    } else if (is401Code.includes(code)) {
        sessionStorage.setItem('is404', 'true')
        hrefRemoveToken()
        return 'error'
    } else if (code !== 200) {
        if(showMessage) ElMessage.error(message)
        return 'error'
    } else {
        return res.data
    }
}

// 回显数据字典
export function selectDictLabel(datas, value) {
    if (value === undefined) {
        return "";
    }
    var actions = [];
    Object.keys(datas).some((key) => {
        if (datas[key].value == ('' + value)) {
            actions.push(datas[key].label);
            return true;
        }
    })
    if (actions.length === 0) {
        actions.push(value);
    }
    return actions.join('');
}

/**
 * 参数处理
 * @param {*} params  参数
 */
export function tansParams(params) {
    let result = ''
    for (const propName of Object.keys(params)) {
        const value = params[propName];
        var part = encodeURIComponent(propName) + "=";
        if (value !== null && value !== "" && typeof (value) !== "undefined") {
            if (typeof value === 'object') {
                for (const key of Object.keys(value)) {
                    if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
                        let params = propName + '[' + key + ']';
                        var subPart = encodeURIComponent(params) + "=";
                        result += subPart + encodeURIComponent(value[key]) + "&";
                    }
                }
            } else {
                result += part + encodeURIComponent(value) + "&";
            }
        }
    }
    return result
}

/**
 * This is just a simple version of deep copy
 * Has a lot of edge cases bug
 * If you want to use a perfect deep copy, use lodash's _.cloneDeep
 * @param {Object} source
 * @returns {Object}
 */
export function deepClone(source) {
    if (!source && typeof source !== 'object') {
        throw new Error('error arguments', 'deepClone')
    }
    const targetObj = source.constructor === Array ? [] : {}
    Object.keys(source).forEach(keys => {
        if (source[keys] && typeof source[keys] === 'object') {
            targetObj[keys] = deepClone(source[keys])
        } else {
            targetObj[keys] = source[keys]
        }
    })
    return targetObj
}

// 加
export const add = (num1, num2) => {
    const SUM = math.add(math.bignumber(num1),math.bignumber(num2));
    return math.number(SUM)
}

// 减
export const subtract = (num1, num2) => {
    const SUM = math.subtract(math.bignumber(num1),math.bignumber(num2));
    return math.number(SUM)
}

// 乘
export const multiply = (num1, num2) => {
    const SUM = math.multiply(math.bignumber(num1),math.bignumber(num2));
    return math.number(SUM)
}

// 除
export const divide = (num1, num2) => {
    const SUM = math.divide(math.bignumber(num1),math.bignumber(num2));
    return math.number(SUM)
}

// 创建随机数
export const createRandom = (min, max) => {
    min = math.ceil(min);
    max = math.floor(max);
    return math.floor(math.random() * (max - min + 1)) + min
}

// 判断数据是否为undefined/null
export const isNil = (value) => {
    return value === null || value === undefined || value === '' || value === 0 || value === false || value === {};
}

// 确保默认数据
export const defaultTo = (target, defaultValue) => {
    if (target === NaN || target === null || target === undefined || target <= -1) return defaultValue
    return target
}

// 对象的forEach遍历方法
export const forIn = (data, fun) => {
    Object.keys(data).forEach((key) => {
        fun(data[key], key)
    })
}

// 判断是否为数组
export const isArray = (data) => {
    if (!Array.isArray) {
        // es5之前不存在该方法,做此兼容
        Array.isArray = function(arg) {
            return Object.prototype.toString.call(arg) === '[object Array]';
        }
    }
    return Array.isArray(data)
}

// loadsh中的every方法
export const every = (array, predicate) => {
    if (!isArray(array)) {
        throw new TypeError('The first argument must be a Array');
    }
    if (typeof predicate !== 'object') {
        throw new TypeError('The second argument must be a object');
    }
    return array.every(item => {
        return item[predicate[0]] === predicate[1]
    })
}

export function defaultsDeep(target, ...sources) {
    // 如果 target 不是对象，则直接返回一个空对象
    if (typeof target !== 'object' || target === null) {
        return {};
    }

    // 遍历所有源对象
    for (const source of sources) {
        // 如果源对象不是对象，则跳过
        if (typeof source !== 'object' || source === null) {
            continue;
        }

        // 递归合并源对象和目标对象
        mergeDeep(target, source);
    }

    return target;
}

export function mergeDeep(target, source) {
    // 遍历源对象的属性
    for (const key in source) {
        // 确保只处理源对象自身的属性
        if (source.hasOwnProperty(key)) {
            const targetValue = target[key];
            const sourceValue = source[key];

            // 如果目标对象的属性值是对象，且源对象的属性值也是对象，则递归合并
            if (
                typeof targetValue === 'object' &&
                targetValue !== null &&
                typeof sourceValue === 'object' &&
                sourceValue !== null
            ) {
                mergeDeep(targetValue, sourceValue);
            }
            // 如果目标对象的属性值为 undefined，则使用源对象的属性值
            else if (targetValue === undefined) {
                target[key] = sourceValue;
            }
        }
    }
}

// 加载资源
export const loadAssets = (name) => {
    return new URL(`../assets/images/${name}.jpg`, import.meta.url).href
}

export const loadView = (view) => {
    let res;
    for (const path in modules) {
        const dir = path.split('views/')[1].split('.vue')[0];
        if (dir === view) {
            res = () => modules[path]();
        }
    }
    return res;
}